package zhh.tangbao.auxiliary.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import zhh.tangbao.auxiliary.common.ReadStatus;
import zhh.tangbao.auxiliary.dao.SystemMessageDao;
import zhh.tangbao.auxiliary.dto.message.SystemMessageQueryDto;
import zhh.tangbao.auxiliary.entity.SystemMessage;
import zhh.tangbao.auxiliary.service.SystemMessageService;
import zhh.tangbao.auxiliary.vo.message.MessageCountStatisticsVo;
import zhh.tangbao.auxiliary.vo.message.MessageCountVo;
import zhh.tangbao.system.utils.UserHolderUtil;
import zhh.tangbao.user.dao.UserDao;
import zhh.tangbao.user.vo.UserAccountAndNameVo;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 描述
 * </p>
 *
 * @author 粥灰灰
 * <p>2023/3/28</p>
 */

@Service
public class SystemMessageServiceImpl implements SystemMessageService {

    @Autowired
    private SystemMessageDao dao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private UserHolderUtil userHolderUtil;

    @Override
    public int batchInsert(String recordUserId, List<String> receiveUserIds, String tittle, String content) {
        if (CollUtil.isEmpty(receiveUserIds)) {
            return 0;
        }
        List<SystemMessage> messages = Lists.newArrayList();
        Date now = new Date();
        for (String receiveUserId : receiveUserIds) {
            SystemMessage message = new SystemMessage();
            message.setReceiveUserId(receiveUserId);
            message.setTitle(tittle);
            message.setContent(content);
            message.setRecordUserId(recordUserId);
            message.setRecordTime(now);
            // isRead默认为0
            messages.add(message);
        }
        return dao.insertBatchSomeColumn(messages);
    }

    @Override
    public int insert(String recordUserId, String receiveUserId, String tittle, String content) {
        SystemMessage entity = new SystemMessage();
        entity.setReceiveUserId(receiveUserId);
        entity.setTitle(tittle);
        entity.setContent(content);
        entity.setRecordUserId(recordUserId);
        entity.setRecordTime(new Date());
        return dao.insert(entity);
    }

    @Override
    public int insertAll(String recordUserId, String tittle, String content) {
        List<SystemMessage> messages = Lists.newArrayList();
        List<String> receiveUserIds = userDao.selectAllUserId();
        if (CollUtil.isEmpty(receiveUserIds)) {
            // 没有用户自然不用插入消息
            return 0;
        }
        Date now = new Date();
        for (int i = 0; i < receiveUserIds.size(); i++) {
            String receiveUserId = receiveUserIds.get(i);
            SystemMessage message = new SystemMessage();
            message.setReceiveUserId(receiveUserId);
            message.setTitle(tittle);
            message.setContent(content);
            message.setRecordUserId(recordUserId);
            message.setRecordTime(now);
            // isRead默认为0
            messages.add(message);
        }
        return dao.insertBatchSomeColumn(messages);
    }

    @Override
    public MessageCountStatisticsVo getUserMessageCount(String userId) {
        MessageCountStatisticsVo vo = new MessageCountStatisticsVo();
        List<MessageCountVo> count = dao.readAndUnReadMessageCountVo(userId);
        if (CollUtil.isEmpty(count)) {
            return vo;
        }
        for (int i = 0; i < count.size(); i++) {
            MessageCountVo m = count.get(i);
            if (m.getIsRead().equals(1)) {
                vo.setRead(m.getCount());
            } else {
                vo.setUnRead(m.getCount());
            }
        }
        return vo;
    }

    @Override
    public Page<SystemMessage> page(SystemMessageQueryDto dto) {
        Page<SystemMessage> page = new Page<>(dto.getPageNum(), dto.getPageSize());
        QueryWrapper<SystemMessage> query = new QueryWrapper<>();
        query.eq("receive_user_id", userHolderUtil.getCurrentUser().getId()).orderByDesc("record_time");
        if (StrUtil.isNotBlank(dto.getTitle())) {
            query.like("title", dto.getTitle());
        }
        if (null != dto.getIsRead()) {
            query.eq("is_read", dto.getIsRead());
        }
        if (null != dto.getStart() && null != dto.getEnd()) {
            query.between("record_time", dto.getStart(), dto.getEnd());
        }
        page = dao.selectPage(page, query);
        List<SystemMessage> records = page.getRecords();
        if (CollUtil.isEmpty(records)) {
            return page;
        }
        List<UserAccountAndNameVo> userAccountAndNameById = userDao.getUserAccountAndNameById(records.stream().map(SystemMessage::getRecordUserId).collect(Collectors.toList()));
        if (CollUtil.isEmpty(userAccountAndNameById)) {
            return page;
        }
        Map<String, UserAccountAndNameVo> collect = userAccountAndNameById.stream().collect(Collectors.toMap(UserAccountAndNameVo::getId, Function.identity()));
        for (int i = 0; i < records.size(); i++) {
            SystemMessage m = records.get(i);
            UserAccountAndNameVo u = collect.get(m.getRecordUserId());
            if (u != null) {
                m.setRecordUserName(u.getUserName());
            }
        }
        return page;
    }

    @Override
    public int batchDelete(List<String> ids) {
        if (CollUtil.isEmpty(ids)) {
            return 0;
        }
        return dao.deleteBatchIds(ids);
    }

    @Override
    public int readMessage(String messageId) {
        SystemMessage update = new SystemMessage();
        update.setIsRead(ReadStatus.READ.getCode());
        return dao.update(update, new QueryWrapper<SystemMessage>().eq("id", messageId));
    }

    @Override
    public int markItAsRead(List<String> messageIds) {
        if (CollUtil.isEmpty(messageIds)) {
            return 0;
        }
        SystemMessage update = new SystemMessage();
        update.setIsRead(ReadStatus.READ.getCode());
        return dao.update(update, new QueryWrapper<SystemMessage>().in("id", messageIds).eq("is_read", ReadStatus.UN_READ.getCode()));
    }

    @Override
    public int markAllAsRead() {
        String id = userHolderUtil.getCurrentUser().getId();
        SystemMessage update = new SystemMessage();
        update.setIsRead(ReadStatus.READ.getCode());
        return dao.update(update, new QueryWrapper<SystemMessage>().eq("is_read", ReadStatus.UN_READ.getCode()).eq("receive_user_id", id));
    }

    @Override
    public SystemMessage getInfo(String id) {
        SystemMessage message = dao.selectById(id);
        Assert.notNull(message, "消息不存在或已被删除");
        List<UserAccountAndNameVo> userAccountAndNameById = userDao.getUserAccountAndNameById(Lists.newArrayList(message.getReceiveUserId(), message.getRecordUserId()));
        if (CollUtil.isEmpty(userAccountAndNameById)) {
            return message;
        }
        userAccountAndNameById.forEach(e -> {
            if (message.getReceiveUserId().equals(e.getId())) {
                message.setReceiveUserName(e.getUserName());
            } else if (message.getRecordUserId().equals(e.getId())){
                message.setRecordUserName(e.getUserName());
            }
        });
        return message;
    }
}
